//============================================================================
// Name        : animation.cpp
// Author      : dfoelber
//============================================================================

#include "object/animation.h"
#include "image_manager.h"
#include "draw/SDL_draw.h"
#include "SDL/SDL_rotozoom.h"

#define sq(x) (x * x)

/**
* Constructor
**/
AnimationObject::AnimationObject() : Object( ImageManager::GetManager()->CreateImage(0,0), OBJECT_ID_ANIMATION, true )
{
	animate = animationOwner = false;
	animIndex = animCounter = 0;
	SetIgnoreCollision(true);
	
	SetBackground( COLOR_BLACK, 0 );
	
	image = ImageManager::GetManager()->CreateImage(0,0);
	colorKey = SDL_MapRGB(image->GetSurface()->format, 255, 255, 255);
}

/**
* Deconstructor
**/
AnimationObject::~AnimationObject()
{
	delete image;
	
	if( animationOwner )
	{
		for( int i = 0; i < (int)anims.size(); i++ )
		{
			delete anims[i];
		}
	}
}

/**
* Lets the object know that time has passed and to move accordingly.
* 
* @param ms The time passed since last called
**/
void AnimationObject::TimePassed( int ms )
{
	Object::TimePassed(ms);
	
	if( duration == DURATION_PATH && !GetPath()->IsMoving() )
	{
		animate = false;
	}
	
	if( animate )
	{
		animCounter += ms;
		if( animCounter >= ANIM_DELAY )
		{
			if( (int)anims.size() > 0 )
			{
				if( animIndex >= (int)anims.size() )
				{
					animIndex = 0;
					if( duration == DURATION_ONCE )
					{
						animate = false;
						return;
					}
				}
				
				Draw_FillRect( image->GetSurface(), 0, 0, image->GetWidth(), image->GetHeight(), COLOR_WHITE.ToUint32() );
				if( rotate )
				{
					Surface* surface = new Surface( rotozoomSurface( anims[animIndex]->GetSurface(), GetPath()->GetRotation(), 1, 0 ) );
					rotoKey = SDL_MapRGB(image->GetSurface()->format, 0, 0, 0);
					SDL_SetColorKey(surface->GetSurface(), SDL_SRCCOLORKEY | SDL_RLEACCEL, rotoKey);
					surface->Apply(this->image, 0, 0);
					delete surface;
				}
				else
				{
					anims[animIndex]->Apply(this->image, 0, 0);
				}
				
				animIndex++;
			}
			
			animCounter = 0;
		}
	}
}

/**
* Sets the animation vector.
* 
* @param anim The animation surfaces
* @param rotate If the animation should rotate
**/
void AnimationObject::SetAnimationImages( vector<Surface*> anim, bool rotate, Duration duration, bool owner )
{
	if( animationOwner )
	{
		for( int i = 0; i < (int)anims.size(); i++ )
		{
			delete anims[i];
		}
	}
	
	animationOwner = owner;
	this->duration = duration;
	this->rotate = rotate;
	animCounter = animIndex = 0;
	anims = anim;
	animate = true;
	
	delete image;
	if( (int)anim.size() > 0 )
	{
		if( rotate )
		{
			int largest = anim[0]->GetWidth() > anim[0]->GetHeight() ? anim[0]->GetWidth() : anim[0]->GetHeight();
			int size = (int)sqrt( sq(largest) * 2 );
			image = ImageManager::GetManager()->CreateImage(size,size);
			GetPath()->SetSize(size,size);
		}
		else
		{
			image = ImageManager::GetManager()->CreateImage(anim[0]->GetWidth(),anim[0]->GetHeight());
			GetPath()->SetSize(anim[0]->GetWidth(),anim[0]->GetHeight());
		}
		
		SDL_SetColorKey(this->image->GetSurface(), SDL_SRCCOLORKEY | SDL_RLEACCEL, colorKey);
		Draw_FillRect( this->image->GetSurface(), 0, 0, image->GetWidth(), image->GetHeight(), COLOR_WHITE.ToUint32() );
		anim[0]->Apply( image, 0, 0 );
	}
	else
	{
		image = ImageManager::GetManager()->CreateImage(0,0);
	}
}
